package com.example.concurrency.thread01;

/**
 * @description: 同步线程的测试
 * @program: demos
 * @author: dove
 * @date: 2020-12-01 22:50
 **/

public class ThreadTest02Async {
    /**
     * 执行结果：
     * i am eating
     * i am singing
     * i am eating
     * i am singing
     * 结果交替出现，因为main线程和new出来的线程是两个线程,异步执行
     *
     * 查看线程运行情况：
     * jps：查看进程号
     * jconsole pid 打开java监视和管理控制台
     */
    public static void main(String[] args) {
        // jdk1.8之前通过匿名内部类创建线程
        // 匿名内部类通过构造器给线程命名,如果不指定线程名，默认从0开始编号: thread-0
        new Thread("dangwen_thread_01"){
            @Override
            public void run() {
                sing();
            }
        //new的方式只是创建了一个线程对线，并没有线程产生，调用start方法后才有了线程并让线程处于就绪状态(runnable)，等待cup调度
        }.start();
        // jdk1.8以后lambda表达式创建线程
//        new Thread(() -> {sing();}).start(); // 调用start方法让线程处于就绪状态，等待cup调度
//        new Thread(ThreadTest02Async::sing).start(); // 调用start方法让线程处于就绪状态，等待cup调度
//        Thread thread = new Thread(ThreadTest02Async::sing);
//        // lambda表达式通过setter方法给线程命名
//        thread.setName("dangwen_thread_02");
//        //In particular, a thread may not be restarted once it has completed execution.
//        thread.start();
//        eat();
        // 知识扩展
        Thread t1 = new Thread("thread_t1"){
            @Override
            public void run() {
                // 打印线程名称，判断执行该方法的线程是哪一个
                System.out.println(Thread.currentThread().getName());
            }
        };
        // 打印输出结果：Main。如果我们调用run方法，跟创建一个普通类，调用一个普通类的run方法没有任何区别。
        // run方法是被main线程执行了。没有新的线程被创建。这样印证了上面写的理论：new出来的时候并没线程产生，调用start方法后，才产生线程。
        t1.run();

    }

    // 一个线程只能被执行一次，线程执行完成后不能被重新启动
    public static void sing() {
        // 线程运行的时候处于运行状态(running)
        while (true){
            System.out.println("i am singing");
            try {
                // sleep让线程处于阻塞状态(blocked)，阻塞时间到了后，线程重新转为就绪状态(runnable)，等待cpu调度
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果这个线程有执行次数，执行完毕后，现在变为终止状态(terminated)
    }

    public static void eat() {
        while (true){
            System.out.println("i am eating");
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
